import sys
from PySide6.QtWidgets import (
    QApplication, QMainWindow, QWidget,
    QPushButton, QHBoxLayout, QVBoxLayout,
    QFileDialog, QSlider, QLabel, QMessageBox
)
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
from PySide6.QtMultimediaWidgets import QVideoWidget
from PySide6.QtCore import Qt, QUrl, QTime, Slot

class VideoPlayer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PySide6 视频播放器（含截图功能）")
        self.resize(800, 680)

        central = QWidget(self)
        self.setCentralWidget(central)

        # 视频显示区
        self.video_widget = QVideoWidget()
        self.video_widget.setAspectRatioMode(Qt.KeepAspectRatio)

        # 媒体播放器 + 音频输出
        self.player = QMediaPlayer(self)
        audio_output = QAudioOutput(self)
        self.player.setAudioOutput(audio_output)
        self.player.setVideoOutput(self.video_widget)

        # 按钮：打开、播放/暂停、截图
        self.open_btn = QPushButton("上传视频")
        self.open_btn.clicked.connect(self.open_file)

        self.play_btn = QPushButton("播放")
        self.play_btn.setEnabled(False)
        self.play_btn.clicked.connect(self.toggle_play)

        self.snapshot_btn = QPushButton("截图")
        self.snapshot_btn.setEnabled(False)
        self.snapshot_btn.clicked.connect(self.take_snapshot)

        # 进度条和时长显示
        self.position_slider = QSlider(Qt.Horizontal)
        self.position_slider.setEnabled(False)
        self.position_slider.sliderMoved.connect(self.seek)

        self.time_label = QLabel("00:00 / 00:00")
        self.time_label.setMinimumWidth(100)

        # 布局
        ctr_layout = QVBoxLayout(central)
        ctr_layout.addWidget(self.video_widget, stretch=1)

        btn_layout = QHBoxLayout()
        btn_layout.addWidget(self.open_btn)
        btn_layout.addWidget(self.play_btn)
        btn_layout.addWidget(self.snapshot_btn)
        ctr_layout.addLayout(btn_layout)

        slider_layout = QHBoxLayout()
        slider_layout.addWidget(self.position_slider, stretch=1)
        slider_layout.addWidget(self.time_label)
        ctr_layout.addLayout(slider_layout)

        # 信号连接：更新进度条与时长
        self.player.positionChanged.connect(self.update_position)
        self.player.durationChanged.connect(self.update_duration)

    def open_file(self):
        path, _ = QFileDialog.getOpenFileName(
            self, "选择视频文件", "", "视频文件 (*.mp4 *.avi *.mov *.mkv)"
        )
        if path:
            url = QUrl.fromLocalFile(path)
            self.player.setSource(url)
            self.play_btn.setEnabled(True)
            self.snapshot_btn.setEnabled(True)
            self.position_slider.setEnabled(True)
            self.play_btn.setText("播放")

    def toggle_play(self):
        if self.player.playbackState() == QMediaPlayer.PlayingState:
            self.player.pause()
            self.play_btn.setText("播放")
        else:
            self.player.play()
            self.play_btn.setText("暂停")

    def take_snapshot(self):
        """抓取当前视频窗口画面并保存为图片"""
        pixmap = self.video_widget.grab()
        if pixmap.isNull():
            QMessageBox.warning(self, "截图失败", "无法获取当前画面。")
            return

        save_path, _ = QFileDialog.getSaveFileName(
            self, "保存截图", "snapshot.png", "PNG 图片 (*.png);;JPEG 图片 (*.jpg *.jpeg)"
        )
        if save_path:
            if pixmap.save(save_path):
                QMessageBox.information(self, "截图成功", f"已保存到：\n{save_path}")
            else:
                QMessageBox.critical(self, "保存失败", "无法保存截图，请检查路径和权限。")

    @Slot(int)
    def update_position(self, position):
        self.position_slider.setValue(position)
        self.refresh_time_label(position, self.player.duration())

    @Slot(int)
    def update_duration(self, duration):
        self.position_slider.setRange(0, duration)
        self.refresh_time_label(self.player.position(), duration)

    def seek(self, position):
        self.player.setPosition(position)

    def refresh_time_label(self, pos_ms, dur_ms):
        fmt = "mm:ss"
        curr = QTime(0, 0, 0).addMSecs(pos_ms).toString(fmt)
        total = QTime(0, 0, 0).addMSecs(dur_ms).toString(fmt)
        self.time_label.setText(f"{curr} / {total}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = VideoPlayer()
    win.show()
    sys.exit(app.exec())
